package com.tuanzi.loan.business.service.system.impl;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.RetryException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tuanzi.loan.business.entity.system.Menu;
import com.tuanzi.loan.business.repository.system.MenuRepository;
import com.tuanzi.loan.business.service.system.MenuService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.exception.SystemException;
import com.tuanzi.loan.core.repository.JPABaseRepository;
import com.tuanzi.loan.core.service.BaseServiceImpl;

/**
 * @author Ray 2017/09/21
 */
@Debug
@Service
@Transactional
@Retryable(value = { RetryException.class })
public class MenuServiceImpl extends BaseServiceImpl<Menu, String> implements MenuService {

	@Autowired
	private MenuRepository menuRepository;

	@Override
	protected JPABaseRepository<Menu, String> getRepository() {
		return menuRepository;
	}

	@Override
	public Menu saveOrUpdate(Menu menu) {
		if (menu.getId() != null && menu.getLeaf() && menuRepository.countByParentId(menu.getId()) > 0) {
			throw new SystemException("该菜单含有子菜单,不能更新为叶子菜单.请移除其下菜单后重试");
		}
		return super.saveOrUpdate(menu);
	}

	@Override
	public void moveMenu(Menu from, Menu to) {
		from.setParentId(to.getId());
		this.saveOrUpdate(from);
	}

	@Override
	public void recurseDisable(Menu root) {
		checkArgument(root != null && root.getId() != null);

		List<Menu> menus = menuRepository.findAllByParentId(root.getId());

		if (!menus.isEmpty()) {
			menus.parallelStream().forEach(this::recurseDisable);
		}
		this.disable(root);
	}

	@Override
	public void recurseDelete(Menu root) {
		checkArgument(root != null && root.getId() != null);

		List<Menu> menus = menuRepository.findAllByParentId(root.getId());

		if (CollectionUtils.isNotEmpty(menus)) {
			menus.parallelStream().forEach(this::recurseDelete);
		}
		menuRepository.delete(root.getId());
	}

	@Override
	public List<Menu> findAllByUserId(String userId) {
		return menuRepository.findAllByUserId(userId);
	}
}
